package com.tbit.uqbike.webmanager.controller;

import cn.hutool.core.util.StrUtil;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.constant.MapConstant;
import com.tbit.uqbike.constant.SysConstant;
import com.tbit.uqbike.constant.UserConstant;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.Point;
import com.tbit.uqbike.object.pojo.BatchAddProhibitArea;
import com.tbit.uqbike.object.pojo.ProhibitArea;
import com.tbit.uqbike.object.pojo.statistics.ExportProhibitArea;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.base.CalibrateService;
import com.tbit.uqbike.service.business.ProhibitAreaService;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.utils.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.*;

import static com.tbit.uqbike.webmanager.controller.BaseController.getLogin;

/**
 * @Author: chen
 * @Description: 禁停区域
 * @Date: 创建于 14:33 2020/3/31
 */
@RestController
@RequestMapping("/prohibitArea")
@Validated
public class ProhibitAreaController {
    @Autowired
    private ProhibitAreaService prohibitAreaService;
    @Autowired
    private CalibrateService calibrateService;

    @RequestMapping("/add")
    @OperateLog(module = ModuleEnum.MAINPARKPOINT, methods = MethodEnum.PROHIBITAREA_ADD)
    public JsonResult add(ProhibitArea prohibitArea, Integer mapType) {
        Assert.notNull(prohibitArea.getAccountId(), "ver.accountId.notNull");
        Assert.notNull(prohibitArea.getName(), "ver.name.notNull");
        Assert.notNull(prohibitArea.getPoints(), "ver.points.notNull");
        if (prohibitArea.getName().length() > 100) {
            throw new BaseException("禁停区名称过长");
        } else if (StrUtil.isNotEmpty(prohibitArea.getRemark()) && prohibitArea.getRemark().length() > 255) {
            throw new BaseException("禁停区备注过长");
        }
        ProhibitArea prohibitAreaByName = prohibitAreaService.getByProhibitAreaName(prohibitArea.getAccountId(), prohibitArea.getName());
        if (prohibitAreaByName != null) {
            throw new BaseException("该运营区内有重复的禁停区名称");
        }
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }
        /**经纬度校准*/
        calibrateService.calProhibitArea(prohibitArea, mapType, MapConstant.MAP_ORI);
        prohibitAreaService.insert(prohibitArea);
        return JsonResult.ok();
    }

    @RequestMapping("/edit")
    @OperateLog(module = ModuleEnum.MAINPARKPOINT, methods = MethodEnum.PROHIBITAREA_EDIT)
    public JsonResult edit(ProhibitArea prohibitArea, Integer mapType) {
        Assert.notNull(prohibitArea.getProhibitAreaId(), "ver.prohibitAreaId.notNull");
        Assert.notNull(prohibitArea.getName(), "ver.name.notNull");
        Assert.notNull(prohibitArea.getPoints(), "ver.points.notNull");
        if (prohibitArea.getName().length() > 100) {
            throw new BaseException("禁停区名称过长");
        } else if (StrUtil.isNotEmpty(prohibitArea.getRemark()) && prohibitArea.getRemark().length() > 255) {
            throw new BaseException("禁停区备注过长");
        }
        ProhibitArea prohibitAreaByName = prohibitAreaService.getByProhibitAreaName(prohibitArea.getAccountId(), prohibitArea.getName());
        if (prohibitAreaByName != null && !Objects.equals(prohibitAreaByName.getProhibitAreaId(), prohibitArea.getProhibitAreaId())) {
            throw new BaseException("该运营区内有重复的禁停区名称");
        }
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }
        /**经纬度校准*/
        calibrateService.calProhibitArea(prohibitArea, mapType, MapConstant.MAP_ORI);
        prohibitAreaService.edit(prohibitArea);
        return JsonResult.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/del")
    @OperateLog(module = ModuleEnum.MAINPARKPOINT, methods = MethodEnum.PROHIBITAREA_DEL)
    public JsonResult del(Integer prohibitAreaId) {
        Assert.notNull(prohibitAreaId, "ver.prohibitAreaId.notNull");
        prohibitAreaService.del(prohibitAreaId);
        return JsonResult.ok();
    }

    /**
     * 分页查询
     */
    @RequestMapping("/queryPage")
    public JsonResult queryPage(String name, Integer accountId, Integer mapType, @RequestParam(defaultValue = "1") Integer pageNO, @RequestParam(defaultValue = "10") Integer rowCount,
                                HttpServletRequest request) {
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }
        LoginInfo loginInfo = getLogin(request);
        // 只有用户是代理商的时候允许为null
        if (loginInfo.type.equals(UserConstant.USER_AGENT)) {
            accountId = loginInfo.id;
        } else {
            Assert.notNull(accountId, "ver.accountId.notNull");
        }
        List<ProhibitArea> list = prohibitAreaService.queryPage(accountId, name, pageNO, rowCount);
        if (list != null && list.size() > 0) {
            calibrateService.celibrateProhibit(list, mapType);
        }
        Integer total = prohibitAreaService.queryCount(accountId, name);
        return JsonResult.ok(list, total);
    }

    /**
     * 获取所有
     */
    @RequestMapping("/getByAccountId")
    public JsonResult getAll(Integer accountId, Integer mapType) {
        if (mapType == null) {
            mapType = MapConstant.MAP_GOOGLE;
        }
        List<ProhibitArea> list = prohibitAreaService.getAll(accountId);
        if (list != null && list.size() > 0) {
            calibrateService.celibrateProhibit(list, mapType);
        }
        return JsonResult.ok(list);
    }

    /**
     * 获取所有
     */
    @RequestMapping("/getByArea")
    public JsonResult getByArea(Integer mapType, Double lo, Double la, Integer accountId, Integer radius) {
        Assert.notNull(accountId, "-10001");
        Assert.notNull(lo, "-2001");
        Assert.notNull(la, "-2002");
        Assert.notNull(radius, "-2003");

        if (mapType == null) {
            mapType = MapConstant.MAP_BAIDU;
        }

        /*校准百度经纬度为原始经纬度*/
        Point point = new Point(lo, la);
        point = calibrateService.commonCalibrate(point, mapType, SysConstant.ORIGINAL);
        List<ProhibitArea> list = prohibitAreaService.getByArea(accountId, point.getX(), point.getY(), radius);
        if (list != null && list.size() > 0) {
            calibrateService.celibrateProhibit(list, mapType);
        }
        return JsonResult.ok(list);
    }

    /**
     * 批量新增模板
     *
     * @return
     */
    @GetMapping("/getBatchAddTemplate")
    public Result<Object> getBatchAddTemplate() {
        ExcelUtil<BatchAddProhibitArea> excelUtil = new ExcelUtil<>(BatchAddProhibitArea.class);
        List<BatchAddProhibitArea> list = new ArrayList<>();
        BatchAddProhibitArea batchAddProhibitArea = new BatchAddProhibitArea();
        batchAddProhibitArea.setProhibitAreaName("test");
        batchAddProhibitArea.setAllowRange(50);
        batchAddProhibitArea.setPoints("114.408613,30.453748;114.408912,30.454289;114.409212,30.453748;113.777498,30.223266;114.409212,30.111111333");
        list.add(batchAddProhibitArea);
        return Result.success(excelUtil.exportExcel(list, "批量新增禁停区信息模板").getData());
    }

    /**
     * 批量导入（禁停区导入）
     *
     * @param file      文件
     * @param accountId 运营区域id
     * @param mapType   地图类型 0:原始 2:高德
     */
    @PostMapping("/batchImport")
    @OperateLog(module = ModuleEnum.MAINPARKPOINT, methods = MethodEnum.PROHIBITAREA_BATCH_ADD)
    public Result<String> batchImport(@RequestParam("file") MultipartFile file, @NotNull Integer accountId,
                                      @RequestParam(defaultValue = "0") Integer mapType, HttpServletRequest request) {
        LoginInfo loginInfo = getLogin(request);
        prohibitAreaService.batchImport(file, accountId, loginInfo, mapType);
        return Result.success();
    }

    /**
     * 获取批量修改禁停区模板
     *
     * @param accountId 区域id
     * @param type      0:空模板，1：带禁停区数据
     * @param mapType   地图类型 0:原始 2:高德
     */
    @GetMapping("/getBatchUpdateProhibitAreaTemplate")
    public Result<Object> getBatchUpdateProhibitAreaTemplate(@NotNull Integer accountId, @NotNull Integer type,
                                                             @RequestParam(defaultValue = "0") Integer mapType) {
        return prohibitAreaService.getBatchUpdateProhibitAreaTemplate(accountId, type, mapType);
    }

    /**
     * 根据excel批量修改禁停区
     *
     * @param file      站点导出的excel文件
     * @param accountId 区域id
     * @param mapType   地图类型 0:原始 2:高德
     */
    @PostMapping("/batchUpdateProhibitArea")
    @OperateLog(module = ModuleEnum.MAINPARKPOINT, methods = MethodEnum.PROHIBITAREA_BATCH_EDIT)
    public Result<String> batchUpdateProhibitArea(@RequestParam("file") MultipartFile file,
                                                  @NotNull Integer accountId,
                                                  @RequestParam(defaultValue = "0") Integer mapType) {
        return prohibitAreaService.batchUpdateProhibitArea(file, accountId, mapType);
    }

    /**
     * 导出禁停区信息
     *
     * @param prohibitAreaName 禁停区名称
     * @param mapType          地图类型 0:原始 2:高德
     */
    @GetMapping("/exportProhibitArea")
    public JsonResult exportProhibitArea(@NotNull Integer accountId, String prohibitAreaName, @RequestParam(defaultValue = "0") Integer mapType) {
        ExcelUtil<ExportProhibitArea> exportProhibitArea = new ExcelUtil<>(ExportProhibitArea.class);
        List<ExportProhibitArea> prohibitAreaList = prohibitAreaService.selectByProhibitAreaName(accountId, prohibitAreaName);
        prohibitAreaList.forEach(v -> {
            calibrateService.calProhibitArea(v, mapType);
        });
        JsonResult jsonResult = exportProhibitArea.exportExcel(prohibitAreaList, "禁停区信息");
        return JsonResult.ok(jsonResult.getData());
    }

}
